home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP07.ZIP / CHAP07 / DATATRAN / IENUMFE.CPP < prev    next >
C/C++ Source or Header  |  1993-05-26  |  6KB  |  273 lines

  1. /*
  2.  * IENUMFE.CPP
  3.  * Data Tranfer Object for Chapter 7
  4.  *
  5.  * IEnumFORMATETC implementation specifically for the Data Tranfer
  6.  * objects.  This enumerator copies the state of the data list in
  7.  * the data object and uses that to maintain what FORMATETCs it knows.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "dataobj.h"
  20.  
  21.  
  22. extern HINSTANCE g_hInst;
  23.  
  24.  
  25. /*
  26.  * CEnumFormatEtc::CEnumFormatEtc
  27.  * CEnumFormatEtc::~CEnumFormatEtc
  28.  *
  29.  * Parameters (Constructor):
  30.  *  punkRef         LPUNKNOWN to use for reference counting.
  31.  */
  32.  
  33. CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN punkRef)
  34.     {
  35.     m_cRef=0;
  36.     m_punkRef=punkRef;
  37.     m_iCur=0;
  38.     m_cItems=0;
  39.     return;
  40.     }
  41.  
  42.  
  43. CEnumFormatEtc::~CEnumFormatEtc(void)
  44.     {
  45.     if (NULL!=m_prgfe)
  46.         {
  47.         LPMALLOC    pIMalloc;
  48.  
  49.         if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  50.             {
  51.             pIMalloc->Free(m_prgfe);
  52.             pIMalloc->Release();
  53.             }
  54.         }
  55.  
  56.     return;
  57.     }
  58.  
  59.  
  60.  
  61. /*
  62.  * CEnumFormatEtc::FInit
  63.  *
  64.  * Purpose:
  65.  *  Copies the FORMATETCs in the data object's listbox into our own,
  66.  *  that is, we make a snapshot for this enumerator.
  67.  *
  68.  * Parameters:
  69.  *  hList           HWND of the listbox containing RENDERINGs
  70.  *
  71.  * Return Value:
  72.  *  BOOL            TRUE if initialization worked, FALSE otherwise.
  73.  */
  74. BOOL CEnumFormatEtc::FInit(HWND hList)
  75.     {
  76.     UINT        i, cItems;
  77.     LPMALLOC    pIMalloc;
  78.     LPRENDERING pRen;
  79.     LPFORMATETC pFE;
  80.     DWORD       cb;
  81.  
  82.     if (NULL==hList)
  83.         return FALSE;
  84.  
  85.     cItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L);
  86.  
  87.     if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  88.         return FALSE;
  89.  
  90.     m_prgfe=(LPFORMATETC)pIMalloc->Alloc(cItems*sizeof(FORMATETC));
  91.     pIMalloc->Release();
  92.  
  93.     if (NULL!=m_prgfe)
  94.         {
  95.         pFE=m_prgfe;
  96.  
  97.         for (i=0; i < cItems; i++)
  98.             {
  99.             cb=SendMessage(hList, LB_GETTEXT, i, (LPARAM)(LPVOID)&pRen);
  100.  
  101.             if (sizeof(LPRENDERING)==cb)
  102.                 {
  103.                 //Copy just the FORMATETC
  104.                 *pFE++=pRen->fe;
  105.                 m_cItems++;
  106.                 }
  107.             }
  108.         }
  109.  
  110.     return TRUE;
  111.     }
  112.  
  113.  
  114.  
  115. /*
  116.  * CEnumFormatEtc::QueryInterface
  117.  * CEnumFormatEtc::AddRef
  118.  * CEnumFormatEtc::Release
  119.  *
  120.  * Purpose:
  121.  *  IUnknown members for CEnumFormatEtc object.  For QueryInterface
  122.  *  we only return out own interfaces and not those of the data object.
  123.  *  However, since enumerating formats only makes sense when the data
  124.  *  object is around, we insure that it stays as long as we stay by
  125.  *  calling an outer IUnknown for ::AddRef and ::Release.  But since we
  126.  *  are not controlled by the lifetime of the outer object, we still keep
  127.  *  our own reference count in order to free ourselves.
  128.  */
  129.  
  130. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  131.     {
  132.     *ppv=NULL;
  133.  
  134.     /*
  135.      * Enumerators do not live on the same level as the data object, so
  136.      * we only need to support out IUnknown and IEnumFORMATETC interfaces
  137.      * here with no concern for aggregation.
  138.      */
  139.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
  140.         *ppv=(LPVOID)this;
  141.  
  142.     //AddRef any interface we'll return.
  143.     if (NULL!=*ppv)
  144.         {
  145.         ((LPUNKNOWN)*ppv)->AddRef();
  146.         return NOERROR;
  147.         }
  148.  
  149.     return ResultFromScode(E_NOINTERFACE);
  150.     }
  151.  
  152.  
  153. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  154.     {
  155.     ++m_cRef;
  156.     m_punkRef->AddRef();
  157.     return m_cRef;
  158.     }
  159.  
  160. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  161.     {
  162.     ULONG       cRefT;
  163.  
  164.     cRefT=--m_cRef;
  165.  
  166.     m_punkRef->Release();
  167.  
  168.     if (0==m_cRef)
  169.         delete this;
  170.  
  171.     return cRefT;
  172.     }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180. /*
  181.  * CEnumFormatEtc::Next
  182.  * CEnumFormatEtc::Skip
  183.  * CEnumFormatEtc::Reset
  184.  * CEnumFormatEtc::Clone
  185.  *
  186.  * Standard enumerator members for IEnumFORMATETC
  187.  */
  188.  
  189. STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE
  190.     , ULONG FAR * pulFE)
  191.     {
  192.     ULONG           cReturn=0L;
  193.  
  194.     if (NULL==m_prgfe)
  195.         return ResultFromScode(S_FALSE);
  196.  
  197.     if (NULL!=pulFE)
  198.         *pulFE=0L;
  199.  
  200.     if (NULL==pFE || m_iCur >= m_cItems)
  201.         return ResultFromScode(S_FALSE);
  202.  
  203.     while (m_iCur < m_cItems && cFE > 0)
  204.         {
  205.         *pFE++=m_prgfe[m_iCur++];
  206.         cReturn++;
  207.         cFE--;
  208.         }
  209.  
  210.     if (NULL!=pulFE)
  211.         *pulFE=(cReturn-cFE);
  212.  
  213.     return NOERROR;
  214.     }
  215.  
  216.  
  217. STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
  218.     {
  219.     if ((m_iCur+cSkip) >= m_cItems)
  220.         return ResultFromScode(S_FALSE);
  221.  
  222.     m_iCur+=cSkip;
  223.     return NOERROR;
  224.     }
  225.  
  226.  
  227. STDMETHODIMP CEnumFormatEtc::Reset(void)
  228.     {
  229.     m_iCur=0;
  230.     return NOERROR;
  231.     }
  232.  
  233.  
  234. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC FAR *ppEnum)
  235.     {
  236.     LPCEnumFormatEtc    pNew;
  237.     LPMALLOC            pIMalloc;
  238.     LPFORMATETC         prgfe;
  239.     BOOL                fRet=TRUE;
  240.     ULONG               cb;
  241.  
  242.     *ppEnum=NULL;
  243.  
  244.     //Copy the memory for the list.
  245.     if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  246.         return ResultFromScode(E_OUTOFMEMORY);
  247.  
  248.     cb=m_cItems*sizeof(FORMATETC);
  249.     prgfe=(LPFORMATETC)pIMalloc->Alloc(cb);
  250.  
  251.     if (NULL!=prgfe)
  252.         {
  253.         //Copy the formats
  254.         _fmemcpy(prgfe, m_prgfe, (int)cb);
  255.  
  256.         //Create the clone
  257.         pNew=new CEnumFormatEtc(m_punkRef);
  258.  
  259.         if (NULL!=pNew)
  260.             {
  261.             pNew->m_iCur=m_iCur;
  262.             pNew->m_prgfe=prgfe;
  263.             pNew->AddRef();
  264.             fRet=TRUE;
  265.             }
  266.         }
  267.  
  268.     pIMalloc->Release();
  269.  
  270.     *ppEnum=pNew;
  271.     return fRet ? NOERROR : ResultFromScode(E_OUTOFMEMORY);
  272.     }
  273.